package com.quickask.serviceImpl;

import com.quickask.dao.*;
import com.quickask.entity.AsknowUserEntity;
import com.quickask.entity.AsknowUserLocationEntity;
import com.quickask.entity.AsknowUserPrivilegeEntity;
import com.quickask.operate.data.Constants;
import com.quickask.operate.data.RandomCode;
import com.quickask.operate.data.ResultCode;
import com.quickask.operate.encode.Geohash;
import com.quickask.operate.encode.MD5_Encode;
import com.quickask.operate.encode.SHA1_Encode;
import com.quickask.operate.qiniu.GenerateUploadToken;
import com.quickask.operate.redis.RedisClientTemplate;
import com.quickask.service.UserService;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by NaSa on 2015/9/3.
 */
public class UserServiceImpl extends BaseServiceImpl implements UserService {

    private UserDao userDao;
    private UserPrivilegeDao userPrivilegeDao;
    private UserAttentionDao userAttentionDao;
    private UserLocationDao userLocationDao;
    private CollectionDao collectionDao;

    @Autowired
    private RedisClientTemplate redisClientTemplate;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void setUserPrivilegeDao(UserPrivilegeDao userPrivilegeDao) {
        this.userPrivilegeDao = userPrivilegeDao;
    }

    public void setUserAttentionDao(UserAttentionDao userAttentionDao) {
        this.userAttentionDao = userAttentionDao;
    }

    public void setUserLocationDao(UserLocationDao userLocationDao) {
        this.userLocationDao = userLocationDao;
    }

    public void setCollectionDao(CollectionDao collectionDao) {
        this.collectionDao = collectionDao;
    }

    @Override
    public void addUser(AsknowUserEntity user) {
        userDao.save(user);
    }

    @Override
    public AsknowUserEntity loadUser(Integer id) {
        return userDao.load(id);
    }

    @Override
    public List<AsknowUserEntity> showAllUser() {
        //System.out.println("手机号码"+userDao.registerByPhone("13560411384","24wt3242te324","86","555"));
        System.out.println("Get All AsknowUser....");
        List<AsknowUserEntity> userList = new ArrayList<AsknowUserEntity>();
        userDao.setCacheQueries(true);
        userList.addAll(userDao.getListByHQL("from AsknowUserEntity as u order by u.userCreateDate desc"));
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("userId", 1);
        List objs = userAttentionDao.getListBySQL("select auae.attentionId,auae.attentionUserId,auae.attentionTime,aue.* from " +
                "asknow_user_attention auae, asknow_user aue where auae.userId = :userId and auae.attentionUserId = aue.userId", map);
        JSONArray jsonArray = new JSONArray();
        for(int i=0;i<objs.size();i++) {
            JSONObject jsonObject = new JSONObject();
            try {
                jsonObject.put("data",objs.get(i));
            } catch (JSONException e) {
                e.printStackTrace();
            }
            jsonArray.put(jsonObject);
        }
        redisClientTemplate.set("username","hackway");
        System.out.println("username: "+redisClientTemplate.get("username"));
        System.out.println("结果: " + jsonArray.toString());
//        Iterator itr = userDao.getListBySQL("select userId,userAccount,userPassword,userNickname,userIcon,userSex," +
//                "userPhone,userQq,userWechat,userCreateDate,userPhoneZoneCode from asknow_user").iterator();
//        List<AsknowUserEntity> userList = new ArrayList<AsknowUserEntity>();
//        while(itr.hasNext()){
//            Object[] obj = (Object[]) itr.next();
//            AsknowUserEntity asknowUserEntity = new AsknowUserEntity();
//            asknowUserEntity.setUserId(Integer.parseInt(String.valueOf(obj[0])));
//            asknowUserEntity.setUserAccount(String.valueOf(obj[1]));
//            asknowUserEntity.setUserPassword(String.valueOf(obj[2]));
//            asknowUserEntity.setUserNickname(String.valueOf(obj[3]));
//            asknowUserEntity.setUserIcon(String.valueOf(obj[4]));
//            asknowUserEntity.setUserSex(Byte.parseByte(String.valueOf(obj[5])));
//            asknowUserEntity.setUserPhone(String.valueOf(obj[6]));
//            asknowUserEntity.setUserQq(String.valueOf(obj[7]));
//            asknowUserEntity.setUserWechat(String.valueOf(obj[8]));
//            Timestamp time = Timestamp.valueOf(String.valueOf(obj[9]));
//            asknowUserEntity.setUserCreateDate(time);
//            asknowUserEntity.setUserPhoneZoneCode(String.valueOf(obj[10]));
//            userList.add(asknowUserEntity);
//            //now you have one array of Object for each row
//            //String client = String.valueOf(obj[0]); // don't know the type of column CLIENT assuming String
//            //Integer service = Integer.parseInt(String.valueOf(obj[1])); //SERVICE assumed as int
//            //same way for all obj[2], obj[3], obj[4]
//        }
        return userList;
    }

    /**
     * 通过手机注册
     * @param phoneNum  手机号码
     * @param passwordNo 密码
     * @param zone 区号，中国为86
     * @param code 短信验证码
     * @return 返回注册结果码,详见ResultCode.java
     */
    @Override
    public int registerByPhone(String phoneNum, String passwordNo, String zone, String code) {
        return userDao.registerByPhone(phoneNum, passwordNo, zone, code);
    }

    /**
     * 普通账号注册
     * @param account 账号
     * @param passwordNo 密码
     * @return 返回注册结果码,详见ResultCode.java
     */
    @Override
    public int registerByNormal(String account, String passwordNo) {
        return userDao.registerByNormal(account,passwordNo);
    }

    /**
     * 通过手机账号登录
     * @param phoneNum 手机号码
     * @param passwordNo 密码
     * @return 返回AsknowUserEntity实体，主要包含生成的用户token
     */
    @Override
    public AsknowUserEntity loginByPhone(String phoneNum, String passwordNo) {
        AsknowUserEntity asknowUserEntity = userDao.loginByPhone(phoneNum, passwordNo);
        if(asknowUserEntity == null) {
            return null;
        } else {
            AsknowUserPrivilegeEntity asknowUserPrivilegeEntity = asknowUserEntity.getAsknowUserPrivilegeEntity();
            if(null == asknowUserPrivilegeEntity) {
                asknowUserPrivilegeEntity = new AsknowUserPrivilegeEntity();
                asknowUserPrivilegeEntity.setUserId(asknowUserEntity.getUserId());
                asknowUserPrivilegeEntity.setUserPoint(0);
//                asknowUserPrivilegeEntity.setRefreshToken(new RandomCode().generateToken());
//                asknowUserPrivilegeEntity.setUserRefreshTokenCreateTime(new RandomCode().generateCurrentTimestamp());
//                asknowUserPrivilegeEntity.setUserRefreshTokenExpireTime(Constants.REFRESH_TOKEN_EXPIRE_TIME);
//                asknowUserPrivilegeEntity.setUserRefreshTokenIsExpire((byte) 0);
            }
            asknowUserPrivilegeEntity.setUserLoginState((byte) 1);
            asknowUserPrivilegeEntity.setUserLastLoginTime(new RandomCode().generateCurrentTimestamp());
            MD5_Encode md5 = new MD5_Encode();
            asknowUserPrivilegeEntity.setUserAlia(md5.getDigestOfString(md5.StringToByteArray(phoneNum)));
            asknowUserEntity.setAsknowUserPrivilegeEntity(asknowUserPrivilegeEntity);
            asknowUserEntity.setUserToken(new RandomCode().generateToken());
            //userDao.update(asknowUserEntity);
            return asknowUserEntity;
        }
    }

    /**
     * 通过普通账号登录
     * @param account 账号
     * @param passwordNo 密码
     * @return 返回AsknowUserEntity实体，主要包含生成的用户token
     */
    @Override
    public AsknowUserEntity loginByNormal(String account, String passwordNo) {
        AsknowUserEntity asknowUserEntity = userDao.loginByNormal(account, passwordNo);
        if(asknowUserEntity == null) {
            return null;
        } else {
            AsknowUserPrivilegeEntity asknowUserPrivilegeEntity = asknowUserEntity.getAsknowUserPrivilegeEntity();
            if(null == asknowUserPrivilegeEntity) {
                asknowUserPrivilegeEntity = new AsknowUserPrivilegeEntity();
                asknowUserPrivilegeEntity.setUserId(asknowUserEntity.getUserId());
                asknowUserPrivilegeEntity.setUserPoint(0);
//                asknowUserPrivilegeEntity.setRefreshToken(new RandomCode().generateToken());
//                asknowUserPrivilegeEntity.setUserRefreshTokenCreateTime(new RandomCode().generateCurrentTimestamp());
//                asknowUserPrivilegeEntity.setUserRefreshTokenExpireTime(Constants.REFRESH_TOKEN_EXPIRE_TIME);
//                asknowUserPrivilegeEntity.setUserRefreshTokenIsExpire((byte) 0);
            }
            MD5_Encode md5 = new MD5_Encode();
            asknowUserPrivilegeEntity.setUserAlia(md5.getDigestOfString(md5.StringToByteArray(account)));
            asknowUserPrivilegeEntity.setUserLoginState((byte) 1);
            asknowUserPrivilegeEntity.setUserLastLoginTime(new RandomCode().generateCurrentTimestamp());
            asknowUserEntity.setAsknowUserPrivilegeEntity(asknowUserPrivilegeEntity);
            asknowUserEntity.setUserToken(new RandomCode().generateToken());
            //userDao.update(asknowUserEntity);
            return asknowUserEntity;
        }
    }

    /**
     * 注销登录
     *
     * @param userId 用户Id
     */
    @Override
    public int logout(Integer userId) {
        AsknowUserPrivilegeEntity asknowUserPrivilegeEntity = userPrivilegeDao.get(userId);
        if(asknowUserPrivilegeEntity == null) { //用户Id错误
            return ResultCode.USERID_ERROR;
        }
        asknowUserPrivilegeEntity.setUserLoginState((byte) 0);
        return ResultCode.SUCCESS;
    }

    /**
     * @param userId 用户id
     * @param token  用户token
     * @return 新的AsknowUserPrivilegeEntity
     */
    @Override
    public Integer updateRefreshToken(Integer userId, String token) {
        int resultCode = userDao.isTokenExist(userId, token);
        if(resultCode == ResultCode.SUCCESS) {
            AsknowUserPrivilegeEntity asknowUserPrivilegeEntity = userPrivilegeDao.get(userId);
            asknowUserPrivilegeEntity.setRefreshToken(new RandomCode().generateToken());
            asknowUserPrivilegeEntity.setUserRefreshTokenExpireTime(Constants.REFRESH_TOKEN_EXPIRE_TIME);
            asknowUserPrivilegeEntity.setUserRefreshTokenCreateTime(new RandomCode().generateCurrentTimestamp());
            asknowUserPrivilegeEntity.setUserRefreshTokenIsExpire((byte) 1);
            //userPrivilegeDao.update(asknowUserPrivilegeEntity);
            return userId;
        }  else {
            return resultCode;
        }
    }

    /**
     * 完善个人信息
     *
     * @param userId     用户id
     * @param properties 更新的属性
     * @return 返回结果码，详见com.quickask.operate.data.ResultCode.java
     */
    @Override
    public int updatePersonalImformation(Integer userId, Map<String, Object> properties) {
        return userPrivilegeDao.updatePersonalImformation(userId,properties);
    }

    /**
     * 更新用户位置信息
     *
     * @param userJson
     * @return
     */
    @Override
    public AsknowUserLocationEntity updateUserLocation(String userJson) {
        try {
            JSONObject jsonObject = new JSONObject(userJson);
            AsknowUserLocationEntity asknowUserLocationEntity = new AsknowUserLocationEntity();
            asknowUserLocationEntity.setUserId(jsonObject.optInt("userId"));
            asknowUserLocationEntity.setAltitude(jsonObject.optDouble("altitude"));
            asknowUserLocationEntity.setLatitude(jsonObject.optDouble("latitude"));
            asknowUserLocationEntity.setLongitude(jsonObject.optDouble("longitude"));
            asknowUserLocationEntity.setLocationDetail(jsonObject.optString("locationDetail"));
            asknowUserLocationEntity.setProvinceCode(jsonObject.optString("provinceCode"));
            asknowUserLocationEntity.setCityCode(jsonObject.optString("cityCode"));
            asknowUserLocationEntity.setBlockCode(jsonObject.optString("blockCode"));
            asknowUserLocationEntity.setGeohash(new Geohash().encode(jsonObject.optDouble("latitude"), jsonObject.optDouble("longitude")));
            asknowUserLocationEntity.setType(Byte.parseByte(jsonObject.get("type").toString()));
            userLocationDao.saveOrUpdate(asknowUserLocationEntity);
            return asknowUserLocationEntity;
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public String loadUserToken(Integer userId) {
        return userDao.loadToken(userId);
    }


    /**
     * 获取实体
     * @param userId
     * @return
     */
    @Override
    public AsknowUserPrivilegeEntity loadAsknowUserPrivilegeEntity(int userId) {
        return userPrivilegeDao.get(userId);
    }

    @Override
    public String generateQiniuToken() {
        return new GenerateUploadToken().getUpToken0();
    }


}
